package com.hmall.trade.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.hmall.api.client.ItemClient;
import com.hmall.api.domain.dto.*;
import com.hmall.api.domain.po.Order;
import com.hmall.api.domain.po.OrderDetail;
import com.hmall.common.exception.BadRequestException;
import com.hmall.common.mq.RabbitMqHelper;
import com.hmall.common.utils.UserContext;
import com.hmall.trade.mapper.OrderMapper;
import com.hmall.trade.service.IOrderDetailService;
import com.hmall.trade.service.IOrderService;
import lombok.RequiredArgsConstructor;
import org.apache.seata.spring.annotation.GlobalTransactional;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2025-08-08
 */
@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    private final IOrderDetailService detailService;

    private final ItemClient itemClient;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RabbitMqHelper rabbitMqHelper;

    @Override
    public void handleNoPayOrder(PayOrderDTO payOrder) {
        //条件判断
        if(payOrder.getStatus()!=3){
            //修改状态
            Order order = new Order();
            order.setId(payOrder.getBizOrderNo());
            order.setStatus(5);
            getBaseMapper().updateById(order);
        }
    }

    @Override
    public void handlerNoPayOrders(Long orderId) {
        //查询订单信息
        Order order = getById(orderId);
        //幂等性判断：只有订单状态为未支付时才处理
        if(order==null || !order.getStatus().equals(1)){
            return;
        }
        //将订单状态修改为已关闭
        Order updateOrder = new Order();
        updateOrder.setId(orderId);
        updateOrder.setStatus(5);
        getBaseMapper().updateById(updateOrder);
        //恢复订单中已经扣减的库存
        //查询订单详情
        QueryWrapper<OrderDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_id",orderId);
        List<OrderDetail> orderDetails = detailService.list(queryWrapper);
        //构建恢复库所需的数据结构
        List<OrderDetailDTO> orderDetailDTOS= orderDetails.stream().map(detail->{
            OrderDetailDTO dto = new OrderDetailDTO();
            dto.setItemId(detail.getItemId());
            dto.setNum(detail.getNum());
            return dto;
        }).collect(Collectors.toList());
        //调用item-service恢复库存
        try {
            itemClient.restoreStock(orderDetailDTOS);
        } catch (Exception e) {
            throw new RuntimeException("恢复库存失败",e);
        }

    }


    @Override
    @GlobalTransactional
    public Long createOrder(OrderFormDTO orderFormDTO) {
        // 1.订单数据
        Order order = new Order();
        // 1.1.查询商品
        List<OrderDetailDTO> detailDTOS = orderFormDTO.getDetails();
        // 1.2.获取商品id和数量的Map
        Map<Long, Integer> itemNumMap = detailDTOS.stream()
                .collect(Collectors.toMap(OrderDetailDTO::getItemId, OrderDetailDTO::getNum));
        Set<Long> itemIds = itemNumMap.keySet();
        // 1.3.查询商品
        List<ItemDTO> items = itemClient.queryItemByIds(itemIds);
        if (items == null || items.size() < itemIds.size()) {
            throw new BadRequestException("商品不存在");
        }
        // 1.4.基于商品价格、购买数量计算商品总价：totalFee
        int total = 0;
        for (ItemDTO item : items) {
            total += item.getPrice() * itemNumMap.get(item.getId());
        }
        order.setTotalFee(total);
        // 1.5.其它属性
        order.setPaymentType(orderFormDTO.getPaymentType());
        order.setUserId(UserContext.getUser());
        order.setStatus(1);
        // 1.6.将Order写入数据库order表中
        save(order);

        // 2.保存订单详情
        List<OrderDetail> details = buildDetails(order.getId(), items, itemNumMap);
        detailService.saveBatch(details);

        // 3.清理购物车商品
        OrderMsgDTO msgDTO = new OrderMsgDTO();
        msgDTO.setUserId(UserContext.getUser());
        msgDTO.setItemIds(new ArrayList<>(itemIds));
        try {
            rabbitMqHelper.sendMessageWithConfirm("trade.topic","order.create",msgDTO,3);
        } catch (Exception e) {
           log.error("订单创建消息发送失败，订单ID:{},用户ID:{},商品ID:{}");
        }
        // 4.扣减库存
        try {
            itemClient.deductStock(detailDTOS);
        } catch (Exception e) {
            throw new RuntimeException("库存不足！");
        }
        return order.getId();
    }

    @Override
    public void markOrderPaySuccess(Long orderId) {
        Order order = new Order();
        order.setId(orderId);
        order.setStatus(2);
        order.setPayTime(LocalDateTime.now());
        updateById(order);
    }

    private List<OrderDetail> buildDetails(Long orderId, List<ItemDTO> items, Map<Long, Integer> numMap) {
        List<OrderDetail> details = new ArrayList<>(items.size());
        for (ItemDTO item : items) {
            OrderDetail detail = new OrderDetail();
            detail.setName(item.getName());
            detail.setSpec(item.getSpec());
            detail.setPrice(item.getPrice());
            detail.setNum(numMap.get(item.getId()));
            detail.setItemId(item.getId());
            detail.setImage(item.getImage());
            detail.setOrderId(orderId);
            details.add(detail);
        }
        return details;
    }
}
